#include "Box.h"

using namespace std;
using namespace CICore;

/// <summary>
/// Constructor
/// </summary>
/// <param name="minb"> The minimum box's vertex </param>
/// <param name="maxb"> The maximum box's vertex </param>
CIGeom::Box::Box (const Vertex& minb, const Vertex& maxb) {
    min = minb;
    max = maxb;
}

/// <summary>
/// Destructor
/// </summary>
CIGeom::Box::~Box() {}








///<************************************************************************************************************>
///<************************************ region Utility PRIVATE Methods ****************************************>
///<************************************************************************************************************>

/// <summary>
/// Method called to render the box
/// </summary>
void CIGeom::Box::Draw() const {
    glNormal3f (0, 0, 1);
    glVertex3f (min.x, min.y, min.z);
    glVertex3f (max.x, min.y, min.z);

    glVertex3f (max.x, min.y, min.z);
    glVertex3f (max.x, max.y, min.z);

    glVertex3f (max.x, max.y, min.z);
    glVertex3f (min.x, max.y, min.z);

    glVertex3f (min.x, max.y, min.z);
    glVertex3f (min.x, min.y, min.z);

    glVertex3f (min.x, min.y, max.z);
    glVertex3f (max.x, min.y, max.z);

    glVertex3f (max.x, min.y, max.z);
    glVertex3f (max.x, max.y, max.z);

    glVertex3f (max.x, max.y, max.z);
    glVertex3f (min.x, max.y, max.z);

    glVertex3f (min.x, max.y, max.z);
    glVertex3f (min.x, min.y, max.z);

    glVertex3f (min.x, max.y, min.z);
    glVertex3f (min.x, max.y, max.z);

    glVertex3f (max.x, max.y, min.z);
    glVertex3f (max.x, max.y, max.z);

    glVertex3f (min.x, min.y, min.z);
    glVertex3f (min.x, min.y, max.z);

    glVertex3f (max.x, min.y, min.z);
    glVertex3f (max.x, min.y, max.z);
    
}
/***************************************************************************************************************
*************************************** endregion Utility PRIVATE Methods **************************************
****************************************************************************************************************/









///<************************************************************************************************************>
///<**************************************** region Utility Methods ********************************************>
///<************************************************************************************************************>

/// <summary>
/// Method called to render the box
/// </summary>
void CIGeom::Box::Render() const {
    glLineWidth (1.0f);

    glBegin (GL_LINES);
        Draw();
    glEnd();
}

/// <summary>
/// Method called to render the box filled
/// </summary>
void CIGeom::Box::RenderFilled() const {
    glBegin (GL_QUADS);        
        glNormal3f (0, 0, -1);
        glVertex3f (min.x, min.y, min.z);
        glVertex3f (max.x, min.y, min.z);
        glVertex3f (max.x, max.y, min.z);
        glVertex3f (min.x, max.y, min.z);

        glNormal3f (-1, 0, 0);
        glVertex3f (min.x, min.y, min.z);
        glVertex3f (min.x, min.y, max.z);
        glVertex3f (min.x, max.y, max.z);
        glVertex3f (min.x, max.y, min.z);

        glNormal3f (0, -1, 0);
        glVertex3f (min.x, min.y, min.z);
        glVertex3f (max.x, min.y, min.z);
        glVertex3f (max.x, min.y, max.z);
        glVertex3f (min.x, min.y, max.z);

        glNormal3f (1, 0, 0);
        glVertex3f (max.x, min.y, min.z);
        glVertex3f (max.x, min.y, max.z);
        glVertex3f (max.x, max.y, max.z);
        glVertex3f (max.x, max.y, min.z);

        glNormal3f (0, 1, 0);
        glVertex3f (min.x, max.y, min.z);
        glVertex3f (min.x, max.y, max.z);
        glVertex3f (max.x, max.y, max.z);
        glVertex3f (max.x, max.y, min.z);

        glNormal3f (0, 0, 1);
        glVertex3f (min.x, min.y, max.z);
        glVertex3f (max.x, min.y, max.z);
        glVertex3f (max.x, max.y, max.z);
        glVertex3f (min.x, max.y, max.z);
    glEnd();
}

/// <summary>
/// Method called to get the box's centre
/// </summary>
/// <returns> The box's centre </returns>
Point CIGeom::Box::GetCentre() const {
     return Point ((max.x+min.x)/2, (max.y+min.y)/2, (max.z+min.z)/2);
}

/// <summary>
/// Method called to update the box so that it contains the vertex v
/// </summary>
/// <param name="v"> The vertex that the box has to contain </param>
void CIGeom::Box::Update (const Vertex& v) {
  if (v.x < min.x) min.x = v.x;
  if (v.y < min.y) min.y = v.y;
  if (v.z < min.z) min.z = v.z;
  if (v.x > max.x) max.x = v.x;
  if (v.y > max.y) max.y = v.y;
  if (v.z > max.z) max.z = v.z;
}
/***************************************************************************************************************
******************************************* endregion Utility Methods ******************************************
****************************************************************************************************************/
